{% extends "base.html" %}
{% set baseurl = ".." %}

{% block header %}
{% endblock %}

{% block content %}
    <h3>Overview</h3>
    <p>This library provides realtime image effects using WebGL. There are three parts to glfx.js:</p>
    <ul>
        <li><b>texture:</b> a raw source of image data (created from an <kbd>&lt;img&gt;</kbd> tag)</li>
        <li><b>filter:</b> an image effect (represents one or more WebGL shaders)</li>
        <li><b>canvas:</b> an image buffer that stores the results (a WebGL <kbd>&lt;canvas&gt;</kbd> tag)</li>
    </ul>
    <p>There are two caveats to glfx.js. First, WebGL is a new technology that is only available in the latest browsers and it will be quite a while before the majority of users have it. Second, due to the same origin policy, JavaScript is only allowed to read images that originate from the same domain as the script reading them, so you may have to host the images you modify.</p>

    <h3 id="quickstart">Quick Start</h3>
    <p>This HTML fragment is all you need to use the API. Copy and paste it into an empty index.html document, make sure that directory also contains <a href="{{ baseurl }}/glfx.js">glfx.js</a> and an image named <a href="{{ baseurl }}/media/image.jpg">image.jpg</a>, and open index.html. You should see the image with the ink filter applied.</p>
    <pre>&lt;script src="glfx.js"&gt;&lt;/script&gt;
&lt;script&gt;

window.onload = function() {
    // try to create a WebGL canvas (will fail if WebGL isn't supported)
    try {
        var canvas = fx.canvas();
    } catch (e) {
        alert(e);
        return;
    }

    // convert the image to a texture
    var image = document.getElementById('image');
    var texture = canvas.texture(image);

    // apply the ink filter
    canvas.draw(texture).ink(0.25).update();

    // replace the image with the canvas
    image.parentNode.insertBefore(canvas, image);
    image.parentNode.removeChild(image);

    // Note: instead of swapping the &lt;canvas&gt; tag with the &lt;img&gt; tag
    // as done above, we could have just transferred the contents of
    // the image directly:
    //
    //     image.src = canvas.toDataURL('image/png');
    //
    // This has two disadvantages. First, it is much slower, so it
    // would be a bad idea to do this repeatedly. If you are going
    // to be repeatedly updating a filter it's much better to use
    // the &lt;canvas&gt; tag directly. Second, this requires that the
    // image is hosted on the same domain as the script because
    // JavaScript has direct access to the image contents. When the
    // two tags were swapped using the previous method, JavaScript
    // actually doesn't have access to the image contents and this
    // does not violate the same origin policy.
};

&lt;/script&gt;
&lt;img id="image" src="image.jpg"&gt;</pre>

    <h3>Core API</h3>
    <div class="doc" id="canvas">
        <h4>Canvas Constructor</h4>
        <p><code>var canvas = fx.canvas();</code></p>
        <p>Before you can apply any filters you will need a canvas, which stores the result of the filters you apply. Canvas creation is done through <kbd>fx.canvas()</kbd>, which creates and returns a new WebGL <kbd>&lt;canvas&gt;</kbd> tag with additional methods specific to glfx.js. This call will throw an error message if the browser doesn't support WebGL.</p>
    </div>
    <div class="doc">
        <h4>Draw Image</h4>
        <p><code>canvas.draw(texture);</code></p>
        <p>This replaces the internal contents of the canvas with the image stored in <kbd>texture</kbd>. All filter operations take place in a chain that starts with <kbd>canvas.draw()</kbd> and ends with <kbd>canvas.update()</kbd>.</p>
        <table class="docs"><tr>
            <td><code>texture</code></td>
            <td>Stores image data, the result of calling <kbd>fx.texture()</kbd>.</td>
        </tr></table>
    </div>
    <div class="doc">
        <h4>Update Screen</h4>
        <p><code>canvas.update();</code></p>
        <p>This replaces the visible contents of the canvas with the internal image result. For efficiency reasons, the internal image buffers are not rendered to the screen every time a filter is applied, so you will need to call <kbd>update()</kbd> on your canvas after you have finished applying the filters to be able to see the result. All filter operations take place in a chain that starts with <kbd>canvas.draw()</kbd> and ends with <kbd>canvas.update()</kbd>.</p>
    </div>
    <div class="doc">
        <h4>Texture Constructor</h4>
        <p><code>var texture = canvas.texture(element);</code></p>
        <p>Creates a texture that initially stores the image from an HTML element. Notice that <kbd>texture()</kbd> is a method on a canvas object, which means if you want to use the same image on two canvas objects you will need two different textures, one for each canvas.</p>
        <table class="docs"><tr>
            <td><code>element</code></td>
            <td>The HTML element to store in the texture, either an <kbd>&lt;img&gt;</kbd>, a <kbd>&lt;canvas&gt;</kbd>, or a <kbd>&lt;video&gt;</kbd>.</td>
        </tr></table>
    </div>
    <div class="doc">
        <h4>Update Texture</h4>
        <p><code>texture.loadContentsOf(element);</code></p>
        <p>Loads the image from an HTML element into the texture. This is more efficient than repeatedly creating and destroying textures.</p>
        <table class="docs"><tr>
            <td><code>element</code></td>
            <td>The HTML element to store in the texture, either an <kbd>&lt;img&gt;</kbd>, a <kbd>&lt;canvas&gt;</kbd>, or a <kbd>&lt;video&gt;</kbd>.</td>
        </tr></table>
    </div>
    <div class="doc">
        <h4>Destroy Texture</h4>
        <p><code>texture.destroy();</code></p>
        <p>Textures will be garbage collected eventually when they are no longer referenced, but this method will free GPU resources immediately.</p>
    </div>

    <h3>Filters</h3>
    <div class="doc">All filters are methods on a canvas object and modify the image that is currently on the canvas. This means you will have to <kbd>draw()</kbd> a texture on the canvas before you can apply a filter to it. For efficiency reasons, the internal image buffers are not rendered to the screen every time a filter is applied, so you will need to call <kbd>update()</kbd> on your canvas after you have finished applying the filters to be able to see the result. For an example, please see the <a href="#quickstart">Quick Start</a> section above.</div>
    {{ docs }}
{% endblock %}
